package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.WeeklySectorData;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.WeeklySectorDataService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.service.file.ExcelProcessorFactory;
import org.sixtynine.stock.service.file.FileDataService;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan this class handle weekly sector data
 */

@Controller
@SessionAttributes
public class WeeklySectorController extends SectorDataController {

	@Autowired
	private GenericService genericService;

	@Autowired
	private FileDataService fileDataService;

	@Autowired
	DataManagerService dataManagerService;

	@Autowired
	private WeeklySectorDataService weeklySectorDataService;

	private static final String BIND_VAL_WEEKLY_SECTOR_DATA = "weeklySectorData";

	@RequestMapping(value = "/admin/weeklysectordata/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {

		return super.search(criteria, request);
	}

	@Override
	protected void setPageData(int sectorId, Date fromDate, Date toDate,
			String sortByFirst, String sortBySecond, GridPramDTO gridPramDTO,
			ModelAndView modelAndView) {
		Page<WeeklySectorData> weeklySectorDataPage = weeklySectorDataService
				.searchWeeklySectorData(sectorId, fromDate, toDate, null, null,
						gridPramDTO);
		modelAndView.addObject("weeklySectorDataPage", weeklySectorDataPage);
	}

	@RequestMapping(value = "/admin/weeklysectordata/add")
	public ModelAndView addMonthlySectorData(HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView(getAddPage());

		bindDummyObject(modelAndView);
		bindSectorList(modelAndView);
		bindFileUpload(modelAndView);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/weeklysectordata/add/file_process")
	public ModelAndView addingWeeklySectorByFile(HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return addSectorDataByFile(request, uploadFile);
	}

	@RequestMapping(value = "/admin/weeklysectordata/add/sector_process")
	public ModelAndView addingSectorByFile(
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return processSectorDataBySector(uploadFile);
	}

	@RequestMapping(value = "/admin/weeklysectordata/add/process")
	public ModelAndView addingWeeklySectorData(
			@Valid @ModelAttribute WeeklySectorData weeklySectorData,
			BindingResult result) {
		ModelAndView modelAndView = null;

		if (weeklySectorData.getDate() == null) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "The date cannot be empty, Please enter a correct date.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		if (DateUtil.checkFutureDate(weeklySectorData.getDate())) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "You can't add a future date. Please enter a current or past record.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		Criterion compleateCriterion = Restrictions.between("date",
				DateUtil.getWeekStart(weeklySectorData.getDate()),
				DateUtil.getWeekEnd(weeklySectorData.getDate()));

		List<BaseEntity> dataList = genericService.findByCriteria(
				compleateCriterion, WeeklySectorData.class);
		if (dataList.size() > 0) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "Data already exists for ."
					+ weeklySectorData.getDate();
			modelAndView.addObject(BIND_VAL_MESSAGE, message);

			loadData(1, -1, weeklySectorData.getSector().getId(), null,
					weeklySectorData.getDate(), weeklySectorData.getDate(),
					modelAndView, null);
			return modelAndView;
		}

		if (!result.hasErrors()) {
			genericService.saveOrUpdate(weeklySectorData);
			modelAndView = new ModelAndView(getPage());

			String message = "Data is successfully inserted.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);

			loadData(1, -1, weeklySectorData.getSector().getId(), null,
					weeklySectorData.getDate(), weeklySectorData.getDate(),
					modelAndView, null);

		} else {
			modelAndView = new ModelAndView(getAddPage());
			bindDummyObject(modelAndView);
			bindSectorList(modelAndView);
			bindFileUpload(modelAndView);
		}

		return modelAndView;
	}

	@RequestMapping(value = "/admin/weeklysectordata/list")
	public ModelAndView listOfWeeklySectorData(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {
		return showList(request, page, totalRecords);
	}

	@RequestMapping(value = "/admin/weeklysectordata/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editWeeklySectorData(HttpServletRequest request,
			@PathVariable Integer id) {
		return showEdit(id);
	}

	@RequestMapping(value = "/admin/weeklysectordata/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingWeeklySectorData(
			@Valid @ModelAttribute("weeklySectorData") WeeklySectorData weeklySectorData,
			BindingResult result, @PathVariable Integer id) {
		return editSectorData(weeklySectorData, result);
	}

	@RequestMapping(value = "/admin/weeklysectordata/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteWeeklySectorData(@PathVariable Integer id) {
		return deleteSectorData(id);
	}

	@RequestMapping(value = "/admin/weeklysectordata/delete/selected")
	public ModelAndView deleteSelectedWeeklySectorData(
			HttpServletRequest request,
			@RequestParam(value = "deleteIds", required = false) Integer[] deleteIds) {
		return deleteSelected(deleteIds);
	}

	@RequestMapping(value = "/admin/weeklysectordata/deleteFiltered")
	public ModelAndView deleteFilteredWeeklySectorData(
			HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView(getPage());

		SessionBean sBean = SessionBean.getInstance(request);
		LoadingSearchCriteria criteria = (LoadingSearchCriteria) sBean
				.getAttr(SEARCH_CRITERIA);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();
		}
		// delete the selected criteria
		weeklySectorDataService.deleteWeeklySectorData(criteria.getSectorId(),
				criteria.getFromDate(), criteria.getToDate());

		// reload the page
		loadData(1, -1, criteria.getSectorId(), null, criteria.getFromDate(),
				criteria.getToDate(), modelAndView, criteria);

		return modelAndView;
	}

	@Override
	protected Class getBaseClass() {
		return WeeklySectorData.class;
	}

	@Override
	protected String getPage() {
		return "admin/weeklysectordata/list";
	}

	@Override
	protected String getEditPage() {
		return "admin/weeklysectordata/edit";
	}

	@Override
	protected void loadData(Integer page, Integer totalRecords,
			BaseEntity shareData, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		WeeklySectorData weeklySectorData = (WeeklySectorData) shareData;
		loadData(page, totalRecords, weeklySectorData.getSector().getId(),
				null, weeklySectorData.getDate(), weeklySectorData.getDate(),
				modelAndView, criteria);

	}

	@Override
	protected String getObjBindName() {
		return "weeklySectorData";
	}

	@Override
	protected String getAddPage() {
		return "admin/weeklysectordata/add";
	}

	@Override
	protected String getExelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_WEEKLY_SECTOR_DATA_LIST;
	}

	@Override
	protected String getSectorExcelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_SECTOR_WEEKLY_DATA_LIST;
	}

	@Override
	protected void bindFileUpload(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_FILE_UPLOAD, new FileUploadForm());
	}

	@Override
	protected void bindDummyObject(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_WEEKLY_SECTOR_DATA,
				new WeeklySectorData());
	}

}
